//-------------------------------------------------------------- 

// chengc linux uart driver subject 

// 2016.3.29 

// 

// Work as console,collect the data from uart2. Then put the data to SQLite3.

//                uart0:Debug 

//                uart1:free 

//                uart2:data path 

//-------------------------------------------------------------- 

   

#include <sys/types.h> 

#include <sys/stat.h> 

#include <fcntl.h>                //文件控制定义 

#include <termios.h>        	  //posix中断控制定义 

#include <errno.h>                //错误定义    

#include <ctype.h> 

#include <stdio.h> 

#include <stdlib.h> 

#include <string.h> 

#include <time.h> 

#include <unistd.h>   

#include "pthread.h" 

#include "uart2.h" 

#include "sqlite3.h"

#include<curl/curl.h>

   
struct serial_config Uart2_Cfg; 

static int serial_fd,beep_fd; 

const int speed_arr[] = { 

B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300, 

B38400, B19200, B9600, B4800, B2400, B1200, B300 

}; 

 
const int name_arr[] = { 

230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300, 

38400, 19200, 9600, 4800, 2400, 1200, 300 

}; 
 

//----------------------------------------------- 

//        print content of uart2.cfg 

//----------------------------------------------- 

void print_serialread() 

{ 

	printf("serialread.dev is %s\n",Uart2_Cfg.serial_dev); 

	printf("Uart2_Cfg.speed is %d\n",Uart2_Cfg.serial_speed); 

	printf("Uart2_Cfg.databits is %d\n",Uart2_Cfg.databits); 

	printf("Uart2_Cfg.stopbits is %d\n",Uart2_Cfg.stopbits); 

	printf("Uart2_Cfg.parity is %c\n",Uart2_Cfg.parity); 

} 

   

//----------------------------------------------- 

//        read uart2.cfg 

//----------------------------------------------- 

void read_uart2_cfg() 

{ 

	FILE *serial_fp; 

	char tmp[10]; 

	   

	//读取配置文件 

	serial_fp = fopen("/etc/uart2.cfg","r"); 

	if(NULL == serial_fp) 

	{ 

		printf("can't open /etc/tq2440_serial.cfg\r\n"); 

	} 

	else 

	{ 

		fscanf(serial_fp, "DEV=%s\n", Uart2_Cfg.serial_dev); 
	   

		fscanf(serial_fp, "SPEED=%s\n", tmp); 

		Uart2_Cfg.serial_speed = atoi(tmp); 

		   

		fscanf(serial_fp, "DATABITS=%s\n", tmp); 

		Uart2_Cfg.databits = atoi(tmp); 

		   

		fscanf(serial_fp, "STOPBITS=%s\n", tmp); 

		Uart2_Cfg.stopbits = atoi(tmp); 

		   

		fscanf(serial_fp, "PARITY=%s\n", tmp); 

		Uart2_Cfg.parity = tmp[0]; 

	} 

   

	fclose(serial_fp); 

	printf("uart cfg read over\r\n"); 

} 

   

//----------------------------------------------- 

//        set boardrate 

//----------------------------------------------- 

void set_speed(int fd) 

{ 

	int i; 

	int status; 

	struct termios Opt; 

	   

	if(tcgetattr(fd,&Opt) != 0){ 

		perror("error: set_speed tcgetattr failed!"); 

		return ; 

	} 

   

	for( i = 0; i < sizeof(speed_arr)/sizeof(int); i++) 

	{ 

		if(Uart2_Cfg.serial_speed == name_arr[i]) 

		{ 

			tcflush(fd, TCIOFLUSH); 

			cfsetispeed(&Opt, speed_arr[i]); 

			cfsetospeed(&Opt, speed_arr[i]); 

			status = tcsetattr(fd, TCSANOW, &Opt); 

			if(status != 0) 

			{ 

				perror("error: set_speed tcsetattr failed!"); 

				return; 

			} 

			tcflush(fd, TCIOFLUSH); 

		} 

	} 

} 

   

   

//----------------------------------------------- 

//        set other parity 

//----------------------------------------------- 

int set_parity(int fd) 

{ 

	struct termios options; 

	   

	if(tcgetattr(fd, &options) != 0) 

	{ 

		perror("error: set_parity tcgetattr failed!"); 

		return(FALSE); 

	} 

	   

	options.c_cflag |= (CLOCAL|CREAD); 

	options.c_cflag &=~CSIZE; 

	   

	//set data bits lenghth 

	switch(Uart2_Cfg.databits) 

	{ 

		case 7: 

		options.c_cflag |= CS7; 

		break; 

		case 8: 

		options.c_cflag |= CS8; 

		break; 

		default: 

		options.c_cflag |= CS8; 

		fprintf(stderr, "Unsupported data size\n"); 

		return(FALSE); 

	} 

   

	switch(Uart2_Cfg.parity) 

	{ 

		case 'n': 

		case 'N': 

		options.c_cflag &= ~PARENB; 

		options.c_iflag &= ~INPCK; 

		break; 

		case 'o': 

		case 'O': 

		options.c_cflag |= (PARODD | PARENB); 

		options.c_iflag |= INPCK; 

		break; 

		case 'e': 

		case 'E': 

		options.c_cflag |= PARENB; 

		options.c_cflag &= ~PARODD; 

		options.c_iflag |= INPCK; 

		break; 

		default: 

		options.c_cflag &= ~PARENB; 

		options.c_iflag &= ~INPCK; 

		fprintf(stderr, "Unsupported parity\n"); 

		return(FALSE); 

	} 

   

	//set stop bits 

	switch(Uart2_Cfg.stopbits) 

	{ 

		case 1: 

		options.c_cflag &= ~CSTOPB; 

		break; 

		case 2: 

		options.c_cflag |= CSTOPB;perror("error: set_parity tcgetattr failed!"); 

		break; 

		default: 

		options.c_cflag &= ~CSTOPB; 

		fprintf(stderr, "Unsupported stop bits\n"); 

		return(FALSE); 

	} 

   

	if(Uart2_Cfg.parity != 'n') 

	options.c_iflag |= INPCK; 

	options.c_cc[VTIME] = 0;        //150,15 seconds 

	options.c_cc[VMIN] = 0; 

	#if 1 

	options.c_iflag |= IGNPAR|ICRNL; 

	options.c_oflag |= OPOST; 

	options.c_iflag &= ~(IXON|IXOFF|IXANY); 

	#endif 

	tcflush(fd, TCIFLUSH); 

	if(tcsetattr(fd, TCSANOW, &options) != 0) 

	{ 

		perror("error: set_parity tcsetattr failed!"); 

		return(FALSE); 

	} 

	return(TRUE); 

} 

   

//----------------------------------------------- 

//        open device 

//----------------------------------------------- 

int open_dev(char *dev) 

{ 

	int fd = open(dev, O_RDWR, 0); 

	if(-1 == fd) 

	{ 

		perror("Can't Open Serial Port"); 

		return -1; 

	} 

	else 

	return fd; 

} 

   

//-------------------------------------------------- 

//        uart initialization 

//-------------------------------------------------- 

void uart2_init(void) 

{ 

	char *dev; 

	int i; 

	   

	read_uart2_cfg(); 

	print_serialread(); 

	   

	dev = Uart2_Cfg.serial_dev; 

	serial_fd = open_dev(dev); 

	   

	if(serial_fd > 0) 

		set_speed(serial_fd); 

	else 

	{ 

		printf("Can't Open Serial Port!\n"); 

		exit(0); 

	} 

	   

	//恢复串口未阻塞状态 

	if (fcntl(serial_fd, F_SETFL, O_NONBLOCK) < 0) 

	{ 

		printf("fcntl failed!\n"); 

		exit(0); 

	} 

   

	//检查是否是终端设备 

	 

	if(isatty(STDIN_FILENO)==0) 

	{ 

		printf("standard input is not a terminal device\n"); 

	} 

	else 

		printf("isatty success!\n"); 

	 

	//设置串口参数 

	if(set_parity(serial_fd) == FALSE) 

	{ 

		printf("Set parity Error\n"); 

		exit(1); 

	} 

} 
  

int main(int argc, char **argv) 

{ 

	//==
	CURL *curl;
	CURLcode res;					 
	
	
	
	sqlite3 *db = NULL; 
	char *zErrMsg = 0; 
	int rc;
	char *sql;
	
	//2016-4-10
	sqlite3_stmt*    stmt; 
	int ret=0;
//	char *sql2;
	
	char rx_buffer[512]; 
	char tx_buffer[] = "this is tquart2_init2440 console\n"; 
	int nread,nwrite; 
	
	//--------------------------------
	int j;
	int k;
	int i_pg_length;
	char pg_startbit[5];
	char pg_length[3];
	char pg_protocal[3];
	char pg_content[64];
	char pg_stopbit[5];  	

	//--------------------------------
	
	
	uart2_init();
	
	rc = sqlite3_open("/myapps/dbs/zigbee.db", &db); //打开数据库
	printf("\r\nthe database is opened!\r\n");
		
	nwrite = write(serial_fd,tx_buffer,sizeof(tx_buffer)); 
	printf("nwrite len=%d\r\n",nwrite);
	
	while(1)
	{
			
		if((nread = read(serial_fd,rx_buffer,512))>0) 
		{ 

			rx_buffer[nread] = '\0'; 

			printf("\nrecv len:%d\r\n",nread); 
			printf("content:%s",rx_buffer); 
			printf("\r\n"); 
						
			//------------------------------------------------
			for (j=0; j<4; j++)
			{
				pg_startbit[k++] = rx_buffer[j];        //取起始位 4位
			}
			pg_startbit[k] = '\0';
			k = 0;
			printf("pg_startbit:%s\r\n",pg_startbit);

			for (j=0; j<2; j++)
			{
				pg_length[k++] = rx_buffer[j+4];        //取包长度 2位
			}
			pg_length[k] = '\0';
			k = 0;
			printf("pg_length:%s\r\n",pg_length);
			
			for (j=0; j<2; j++)
			{
				pg_protocal[k++] = rx_buffer[j+6];      //取协议号 2位
			}
			pg_protocal[k] = '\0';
			k = 0;
			printf("pg_protocal:%s\r\n",pg_protocal);
			
			////求包内容长度
			sscanf( pg_length, "%d", &i_pg_length);     // 将字符串转换成整数
			printf("i_pg_length:%d\r\n",i_pg_length);
			
			for (j=0; j<(i_pg_length-2); j++)
			{
				pg_content[k++] = rx_buffer[j+8];       //取包内容 (i_pg_length-2)位
			}
			pg_content[k] = '\0';
			k = 0;
			printf("pg_content:%s\r\n",pg_content);
			
			for (j=0; j<4; j++)
			{
				pg_stopbit[k++] = rx_buffer[j+8+(i_pg_length-2)];    //取停止位 4位
			}
			pg_stopbit[k] = '\0';
			k = 0;
			printf("pg_stopbit:%s\r\n",pg_stopbit);		
			//------------------------------------------------------
			
			if ((strcmp(pg_startbit,"7878")==0)&&(strcmp(pg_stopbit,"0D0A")==0))
			{
				printf("The package is correct!\r\n");
				
				char ss_data[4];
				char ss_noteNumber[9];
				char ss_place[9] = "";
				char xg_point[4];
				char xg_cardNumber[9];
				char xg_who[9] = ""; 
				char deviceNumber[9];	
			
				char sql[128] = "";
				char mid[] = "','";
				char end1[] = "');";
				char end2[] = "';";
				
				char sq_status[] = "notRegistered";
				char zx_status[] = "notCancelled";
				
				//
				char get_fields[128] = "";
				char get_mid[] = "&pk=";

				

				//选择表格
				//sql
				if (strcmp(pg_protocal,"01")==0)
				{
					for (j=0; j<3; j++)
					{
						ss_data[k++] = pg_content[j];        //取ss_data 3位
					}
					ss_data[k] = '\0';
					k = 0;
					printf("ss_data:%s\r\n",ss_data);		
					
					for (j=0; j<8; j++)
					{
						ss_noteNumber[k++] = pg_content[j+3];        //取ss_noteNumber 8位
					}
					ss_noteNumber[k] = '\0';
					k = 0;
					printf("ss_noteNumber:%s\r\n",ss_noteNumber);
					
					//查询节点					 
					strcpy(sql,"SELECT place FROM note_registered WHERE noteNumber=?"); 
					ret = sqlite3_prepare(db,sql,strlen(sql),&stmt,NULL); 
					sqlite3_bind_text(stmt, 1, ss_noteNumber,strlen(ss_noteNumber),SQLITE_STATIC);
					while( sqlite3_step(stmt) == SQLITE_ROW)
					{
						strcpy(ss_place,sqlite3_column_text(stmt,0)); 
					}
					printf("ss_place:%s\r\n",ss_place);
					
					memset(sql,0,128);
					
					if(strlen(ss_place)!=0)
					{
						strcpy(sql," INSERT INTO current_msg(thisNote,data) VALUES('");
						strcat(sql,ss_place);
						strcat(sql,mid);
						strcat(sql,ss_data);
						strcat(sql,end1);
					}
					else
						printf("The package was throw away!\r\n");
					
					/* strcpy(sql," INSERT INTO current_msg(point1,point2,point3) VALUES('");
					strcat(sql,point1_d);
					strcat(sql,mid);
					strcat(sql,point2_d);
					strcat(sql,mid);
					strcat(sql,point3_d);
					strcat(sql,end1); */
				}
				else if (strcmp(pg_protocal,"02")==0)
				{
					for (j=0; j<3; j++)
					{
						xg_point[k++] = pg_content[j];        //xg_point 3位
					}
					xg_point[k] = '\0';
					k = 0;
					printf("xg_point:%s\r\n",xg_point);		
					
					for (j=0; j<8; j++)
					{
						xg_cardNumber[k++] = pg_content[j+3];        //xg_cardNumber 8位
					}
					xg_cardNumber[k] = '\0';
					k = 0;
					printf("xg_cardNumber:%s\r\n",xg_cardNumber);	
					
					//查询人员					 
					strcpy(sql,"SELECT who FROM card_registered WHERE cardNumber=?"); 
					ret = sqlite3_prepare(db,sql,strlen(sql),&stmt,NULL); 
					sqlite3_bind_text(stmt, 1, xg_cardNumber,strlen(xg_cardNumber),SQLITE_STATIC);
					while( sqlite3_step(stmt) == SQLITE_ROW)
					{
						strcpy(xg_who,sqlite3_column_text(stmt,0)); 
					}
					printf("xg_who:%s\r\n",xg_who);
					
					memset(sql,0,128);
					
					if(strlen(xg_who)!=0)
					{
						strcpy(sql," INSERT INTO xg_record(thisPoint,who) VALUES('");
						strcat(sql,xg_point);
						strcat(sql,mid);
						strcat(sql,xg_who);
						strcat(sql,end1);
					}
					else
						printf("The package was throw away!\r\n");
					
					/* strcpy(sql," INSERT INTO xg_record(thisPoint,who) VALUES('");
					strcat(sql,xg_point);
					strcat(sql,mid);
					strcat(sql,xg_who);
					strcat(sql,end1); */
				}
				else if (strcmp(pg_protocal,"03")==0)
				{
					//sql = "" ; //无
				}
				else if (strcmp(pg_protocal,"04")==0)
				{
					for (j=0; j<8; j++)
					{
						deviceNumber[k++] = pg_content[j];        //deviceNumber 8位
					}
					deviceNumber[k] = '\0';
					k = 0;
					printf("deviceNumber:%s\r\n",deviceNumber);		
					
					strcpy(sql," INSERT INTO device_requested(deviceNumber,isRegistered) VALUES('");
					strcat(sql,deviceNumber);
					strcat(sql,mid);
					strcat(sql,sq_status);
					strcat(sql,end1);
				}
				else if (strcmp(pg_protocal,"05")==0)
				{
					for (j=0; j<8; j++)
					{
						deviceNumber[k++] = pg_content[j];        //deviceNumber 8位
					}
					deviceNumber[k] = '\0';
					k = 0;
					printf("deviceNumber:%s\r\n",deviceNumber);	
					
					strcpy(sql," INSERT INTO device_unrequested(deviceNumber,isCancelled) VALUES('");
					strcat(sql,deviceNumber);
					strcat(sql,mid);
					strcat(sql,zx_status);
					strcat(sql,end1);
				}
				else 
					;
				//	sql = "";
			//		
				printf("sql:%s\r\n",sql);
				
				sqlite3_exec( db , sql , 0 , 0 , &zErrMsg ); 

				//curl get
				//-------------------------------------------------------------
				if ((strcmp(pg_protocal,"01")==0)||(strcmp(pg_protocal,"02")==0)||(strcmp(pg_protocal,"04")==0)||(strcmp(pg_protocal,"05")==0))
				{
					strcpy(get_fields,"http://weixlink.applinzi.com/data_performance.php?op=");
					
					strcat(get_fields,pg_protocal);
					strcat(get_fields,get_mid);
					strcat(get_fields,pg_content);
					printf("get_fields:%s\r\n",get_fields);
									
					//==
					/* CURL *curl;
					CURLcode res;					 
					curl = curl_easy_init(); */
					
					curl = curl_easy_init();
					if(curl) 
					{
						curl_easy_setopt(curl, CURLOPT_URL, get_fields);
						/* example.com is redirected, so we tell libcurl to follow redirection */ 
						curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

						/* Perform the request, res will get the return code */ 
						res = curl_easy_perform(curl);
						/* Check for errors */ 
						if(res != CURLE_OK)
							fprintf(stderr, "curl_easy_perform() failed: %s\n",
						curl_easy_strerror(res));

						/* always cleanup */ 
						curl_easy_cleanup(curl);
					}
					//===
					
			
				}	 
				
				//=============================================================
			}
			else
			{
				printf("The package is wrong!\r\n");
			}
			
		} 
	}

	sqlite3_close(db); //关闭数据库 
	printf("the database is closed!"); 
	
	close(serial_fd);  //关闭串口
				
	return 0; 
	

} 
